home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
languags
/
cc.1
< prev
next >
Wrap
Text File
|
1989-04-26
|
43KB
|
1,732 lines
Path: xanth!ames!purdue!tut.cis.ohio-state.edu!bloom-beacon!apple!oliveb!sun!rishathra!page
From: page%rishathra@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i099: cc - unix-like front end for lattice 5.x
Message-ID: <101403@sun.Eng.Sun.COM>
Date: 26 Apr 89 21:36:34 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 1721
Approved: page@sun.com
Submitted-by: bader+@andrew.cmu.edu (Miles Bader)
Posting-number: Volume 89, Issue 99
Archive-name: languages/cc.1
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# Makefile
# README
# builtins.make
# cc.c
# cc.doc
# config.h
# dstr.c
# dstr.h
# err.c
# list.c
# list.h
# op.c
# op.h
# options.c
# options.h
# This is archive 1 of a 1-part kit.
# This archive created: Wed Apr 26 14:31:28 1989
echo "extracting Makefile"
sed 's/^X//' << \SHAR_EOF > Makefile
XDEBUG= -O
XOPTS= +no-stack-check
XFLAGS= $(DEBUG) $(OPTS)
XCFLAGS= $(FLAGS) $(DEFINES)
XLFLAGS= $(FLAGS)
X
XLIBS=
X
XTARGET= cc
XOBJS= cc.o list.o dstr.o err.o op.o options.o
X
X$(TARGET): $(OBJS)
X ${CC} $(LFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
X
X$(OBJS): common.h
Xcc.o: list.h dstr.h op.h options.h config.h
Xcommon.h: dbug.h
Xoptions.o: options.h
Xdstr.o: dstr.h
Xlist.o: list.h
Xop.o: op.h
SHAR_EOF
echo "extracting README"
sed 's/^X//' << \SHAR_EOF > README
XSimple changes to cc's defaults can be made in config.h. If you make a not-
Xso-simple change, to implement some new feature, please send me back the
Xchanges. My email address is bader+@andrew.cmu.edu.
X
XThe Makefile and builtins.make (which goes in s: and defines default rules)
Xare for the version of make that comes with pcc 3.0 (although I just noticed,
Xit's ignoring time-stamps! Anyone got a better make?)
X
X-Miles
SHAR_EOF
echo "extracting builtins.make"
sed 's/^X//' << \SHAR_EOF > builtins.make
XCC=cc
X
X.SUFFIXES: .c .o
X
X.c.o:
X ${CC} -c ${CFLAGS} $<
SHAR_EOF
echo "extracting cc.c"
sed 's/^X//' << \SHAR_EOF > cc.c
X/*
X * cc -- unix-like compiler driver for amiga lattice c
X *
X * adapted for lattice version 5.0 and extensively modified
X * by Miles Bader, from the original by Fred Fish (copyright
X * follows).
X */
X
X/************************************************************************
X * *
X * Copyright (c) 1985, Fred Fish *
X * All Rights Reserved *
X * *
X * This software and/or documentation is released into the *
X * public domain for personal, non-commercial use only. *
X * Limited rights to use, modify, and redistribute are hereby *
X * granted for non-commercial purposes, provided that all *
X * copyright notices remain intact and all changes are clearly *
X * documented. The author makes no warranty of any kind with *
X * respect to this product and explicitly disclaims any implied *
X * warranties of merchantability or fitness for any particular *
X * purpose. *
X * *
X ************************************************************************
X */
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
X#include <dos.h>
X#include <proto/dos.h>
X#include <ios1.h> /* magic */
X
X#include "common.h"
X#include "list.h"
X#include "dstr.h"
X#include "op.h"
X#include "options.h"
X
X#include "config.h"
X
Xstatic char *locate(char *file,struct list *list); /* find a file */
Xstatic void cleanObjects(int mustExist); /* Remove .o for link and go mode */
Xstatic int makeObjs(); /* Reduce to list of object files */
Xstatic int parseCommandLine(); /* Deal with command line */
Xstatic int compile(struct op *op); /* Translate from .c to .o */
Xstatic int assemble(struct op *op); /* Translate from .s to .o */
Xstatic int link(); /* Gather .o's into executable */
Xstatic int runCmd(struct dstr *cmd);
X
X#ifdef amiga
X#define CHECK_ABORT chkabort()
X#else
X#define CHECK_ABORT /* NULL expansion */
X#endif /* amiga */
X
XDBUG_GLOBALS
X
X/*
X * flags set by command line arguments
X */
Xstatic int debugLevel=DEFAULT_DEBUGLEVEL; /* -g (debugging level) */
X
Xstruct list *libDirs=NULL;
Xstruct list *incDirs=NULL;
Xstruct list *binDirs=NULL;
Xstruct list *defines=NULL;
Xstruct list *undefines=NULL;
Xstruct list *libs=NULL;
X
Xstruct list *pass1PassThrus=NULL;
Xstruct list *pass2PassThrus=NULL;
Xstruct list *optPassThrus=NULL;
Xstruct list *linkPassThrus=NULL;
X
Xstruct list *ops=NULL;
X
Xstatic char *outfile=DEFAULT_EXEC; /* output file name from linker */
Xstatic char *tempDir=TEMPDIR; /* where to keep quad files */
Xstatic char *sinkFile=SINKFILE; /* where to put output from passes */
X
Xstruct dstr *cmdLine=NULL;
X
Xstatic int abortmsg()
X{
X if(options_IsSet(OPT_ECHO))
X fprintf(stderr,"cc: aborting\n");
X return 1; /* abort */
X}
X
Xstatic int cleanup(status)
Xint status;
X{
X if(cmdLine!=NULL) dstr_Free(cmdLine);
X
X if(libDirs!=NULL) list_Free(libDirs);
X if(incDirs!=NULL) list_Free(incDirs);
X if(binDirs!=NULL) list_Free(binDirs);
X if(defines!=NULL) list_Free(defines);
X if(undefines!=NULL) list_Free(undefines);
X if(libs!=NULL) list_Free(libs);
X
X if(pass1PassThrus!=NULL) list_Free(pass1PassThrus);
X if(pass2PassThrus!=NULL) list_Free(pass2PassThrus);
X if(optPassThrus!=NULL) list_Free(optPassThrus);
X if(linkPassThrus!=NULL) list_Free(linkPassThrus);
X
X if(ops!=NULL) list_Free(ops);
X
X return status;
X}
X
Xstatic void init()
X{
X int *opt;
X
X options_Init();
X for(opt=defaultOptions; *opt!=0; opt++)
X options_Set(*opt);
X
X cmdLine=dstr_Create(30); /* global command buffer */
X
X libDirs=list_Create((void **)libDirsInit);
X incDirs=list_Create((void **)incDirsInit);
X binDirs=list_Create((void **)binDirsInit);
X defines=list_Create((void **)definesInit);
X undefines=list_Create((void **)undefinesInit);
X libs=list_Create((void **)libsInit);
X
X pass1PassThrus=list_Create(NULL);
X pass2PassThrus=list_Create(NULL);
X optPassThrus=list_Create(NULL);
X linkPassThrus=list_Create(NULL);
X
X ops=list_Create(NULL);
X list_SetFree(ops,op_Free);
X}
X
Xvoid main(argc, argv)
Xint argc;
Xchar *argv[];
X{
X int status;
X
X DBUG_ENTER("main");
X
X onexit(cleanup);
X init();
X
X onbreak(abortmsg);
X
X if(parseCommandLine(argc,argv)==0)
X fatal("no files specified");
X
X cleanObjects(FALSE); /* get rid of existing object files if any */
X
X status=makeObjs();
X if(status==0 && options_IsSet(OPT_LINK)){
X status=link();
X if(list_GetLen(ops)==1)
X cleanObjects(TRUE);
X }
X
X exit(status);
X}
X
X/*
X * The following macro is used to allow optional whitespace between
X * an option and it's argument. Argp is left pointing at the option
X * and argv and argc are adjusted accordingly if necessary.
X *
X * Note that there is no check for missing option arguments. In
X * particular, -o -V will blindly take -V as the output file name.
X *
X */
X
X#define XARG(argc,argv,argp) {if(*++argp=='\0'){argp=(*argv++);argc--;}}
X
Xstatic int parseCommandLine(argc,argv)
Xint argc;
Xchar **argv;
X{
X register char *argp;
X
X DBUG_ENTER("parseCommandLine");
X
X argc--;
X argv++;
X while(argc-- > 0){
X CHECK_ABORT;
X
X argp=*argv++;
X
X if(*argp=='+')
X options_SetByName(argp+1);
X else if(*argp!='-')
X list_Add(ops,(void *)op_Create(argp));
X else
X switch(*++argp){
X case 'c':
X options_Clear(OPT_LINK); /* don't link object modules */
X break;
X case 'p': /* pass thru args to a pass */
X switch(*++argp){
X case '1': /* pass 1 */
X XARG(argc,argv,argp);
X list_Add(pass1PassThrus,argp);
X break;
X case '2': /* pass 2 */
X XARG(argc,argv,argp);
X list_Add(pass2PassThrus,argp);
X break;
X case 'o': /* optimizer */
X XARG(argc,argv,argp);
X list_Add(optPassThrus,argp);
X break;
X case 'l': /* linking */
X XARG(argc,argv,argp);
X list_Add(linkPassThrus,argp);
X break;
X default:
X fatal("unknown pass '%c'; must be one of [12ol]",argp[-1]);
X }
X break;
X case 'D':
X XARG(argc,argv,argp);
X list_Add(defines,(void *)argp);
X break;
X case 'E':
X warning("-E unimplemented, converted to -P instead");
X /* fall through */
X case 'P':
X options_Clear(OPT_COMPILE);
X options_Clear(OPT_ASSEMBLE);
X options_Clear(OPT_LINK);
X break;
X case 'g':
X if(*++argp!='\0') /* optional debuggin level */
X debugLevel=atoi(argp);
X options_Set(OPT_DEBUG);
X break;
X case 'I':
X XARG(argc,argv,argp);
X list_Add(incDirs,(void *)argp);
X break;
X case 'l':
X XARG(argc,argv,argp);
X list_Add(libs,(void *)argp);
X break;
X case 'L':
X XARG(argc,argv,argp);
X list_Add(libDirs,(void *)argp);
X break;
X case 'B':
X XARG(argc,argv,argp);
X list_Add(binDirs,(void *)argp);
X break;
X case 'O':
X options_Set(OPT_OPTIMIZE);
X break;
X case 'o':
X XARG(argc,argv,argp);
X outfile=argp;
X break;
X case 't': /* warning, non-standard */
X XARG(argc,argv,argp);
X tempDir=argp;
X break;
X case 'S':
X warning("-S option not yet implemented, ignored");
X options_Clear(OPT_ASSEMBLE);
X break;
X case 'U':
X XARG(argc,argv,argp);
X list_Add(undefines,(void *)argp);
X break;
X default:
X fatal("unknown option '%c'",*argp);
X break;
X }
X }
X
X DBUG_RETURN(int,list_GetLen(ops));
X}
X
X/*
X * For each operand, do compilation or assembly as necessary, to
X * reduce to an object file in the current directory.
X */
Xstatic int makeObjs()
X{
X int n;
X void **els;
X int numOps=list_GetLen(ops);
X int status=0;
X
X DBUG_ENTER("makeObjs");
X
X for(n=numOps,els=list_GetEls(ops); n>0; n--,els++){
X struct op *op=(struct op *)*els;
X
X CHECK_ABORT;
X
X if(numOps>1 && (op_IsC(op) || op_IsS(op)))
X printf("%s.%s:\n",op->rootname,op->suffix);
X
X if(op_IsC(op))
X status=compile(op);
X else if(op_IsS(op))
X status=assemble(op);
X }
X
X DBUG_RETURN(int,status);
X}
X
X/* handy little routine */
Xvoid addfList(ds,fmt,list)
Xstruct dstr *ds;
Xchar *fmt;
Xstruct list *list;
X{
X int n;
X void **els;
X
X for(n=list_GetLen(list),els=list_GetEls(list); n>0; n--,els++)
X dstr_Addf(ds,fmt,(char *)*els);
X}
X
X/*
X * Note that commands to cc of the form "-l<name>" get interpreted
X * to mean use a library called "name.lib" from the library
X * directory.
X * -lm is specially interpreted to be the appropriate math library.
X */
Xstatic int link()
X{
X int n;
X void **els;
X
X DBUG_ENTER("link");
X
X dstr_Clear(cmdLine);
X
X dstr_Addf(cmdLine,"%s ",locate("blink",binDirs));
X
X if(options_IsSet(OPT_DETACH))
X dstr_Append(cmdLine,locate("cback.o",libDirs));
X else if(options_IsSet(OPT_RESIDENT)){
X if(options_IsSet(OPT_CATCH))
X dstr_Append(cmdLine,locate("catchres.o",libDirs));
X else
X dstr_Append(cmdLine,locate("cres.o",libDirs));
X }else if(options_IsSet(OPT_CATCH))
X dstr_Append(cmdLine,locate("catch.o",libDirs));
X else
X dstr_Append(cmdLine,locate("c.o",libDirs));
X
X for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
X struct op *op=(struct op *)*els;
X char *name=(op_IsO(op) ? op->rootname : op->basename);
X
X dstr_Addf(cmdLine,"+%s.o",name);
X }
X
X if(options_IsSet(OPT_TINYMAIN))
X dstr_Addf(cmdLine," define __main=__tinymain ");
X
X dstr_Addf(cmdLine," library ");
X for(n=list_GetLen(libs),els=list_GetEls(libs); n>0; n--,els++){
X char buffer[50];
X char *lib=(char *)*els;
X
X if(strcmp(lib,"m")==0){
X /* map -lm to appropiate library */
X
X strcpy(buffer,"lib:lcm");
X
X if(options_IsSet(OPT_FFP))
X strcat(buffer,"ffp");
X else if(options_IsSet(OPT_IEEE))
X strcat(buffer,"ieee");
X else if(options_IsSet(OPT_881))
X strcat(buffer,"881");
X
X /*
X * there are only r and s libraries for lcm.lib in the lattice
X * distribution; if there is a way to get the lcmieee, lcmffp,
X * & lcm881 libraries to work with reg-args & short-ints, I
X * couldn't find it.
X */
X if(options_IsSet(OPT_SHORTINTS))
X strcat(buffer,"s");
X if(options_IsSet(OPT_REGARGS))
X strcat(buffer,"r");
X
X strcat(buffer,".lib");
X }else if(strcmp(lib,"lc")==0){
X /* do the standard c library */
X
X strcpy(buffer,"lib:lc");
X
X if(options_IsSet(OPT_SHORTINTS))
X strcat(buffer,"s");
X if(options_IsSet(OPT_REGARGS))
X strcat(buffer,"r");
X if(options_IsSet(OPT_ABSDATA))
X strcat(buffer,"nb");
X
X strcat(buffer,".lib");
X
X if(options_IsSet(OPT_REGARGS)){
X /*
X * Now, do it AGAIN, but without registers, to catch any missing refs.
X * I don't think this is exactly the right thing to do, but there seem
X * to be internal functions missing from the register-fied libraries
X */
X
X strcat(buffer,"+lib:lc");
X
X if(options_IsSet(OPT_SHORTINTS))
X strcat(buffer,"s");
X if(options_IsSet(OPT_ABSDATA))
X strcat(buffer,"nb");
X
X strcat(buffer,".lib");
X }
X }else{
X sprintf(buffer,"%s.lib",lib);
X strcpy(buffer,locate(buffer,libDirs));
X }
X
X if(n==1)
X dstr_Append(cmdLine,buffer);
X else
X dstr_Addf(cmdLine,"%s+",buffer);
X }
X
X if(outfile==NULL)
X /* there better be at least one source file! */
X outfile=((struct op *)list_GetEls(ops))->basename;
X
X dstr_Addf(cmdLine," to %s map nil:",outfile);
X
X addfList(cmdLine," %s",linkPassThrus);
X
X DBUG_RETURN(int,runCmd(cmdLine));
X}
X
X/*
X * compile one operand from a C source program to an object module.
X */
Xstatic int compile(op)
Xstruct op *op;
X{
X int status=0;
X
X DBUG_ENTER("compile");
X
X if(options_IsSet(OPT_ASSEMBLE)){
X status=pass1(op);
X if(status==0 && options_IsSet(OPT_COMPILE)){
X CHECK_ABORT;
X if(options_IsSet(OPT_OPTIMIZE))
X status=optimize(op);
X if(status==0)
X status=pass2(op);
X }
X }
X
X DBUG_RETURN(int,status);
X}
X
X/*
X * Note that because of brain-damage in the fact that -p to lc1 removes
X * all predefined defs, we must add them so replacing -c with -P in the
X * cc command line will result in the same set of predefined symbols.
X * This is rather ugly and leaves a hole for future problems if we
X * get out of sync with respect to what names the compiler predefines.
X */
Xstatic int pass1(op)
Xregister struct op *op;
X{
X char tmpFile[MAXPATH];
X int status;
X int n;
X void **els;
X
X DBUG_ENTER("pass1");
X
X dstr_Clear(cmdLine);
X
X dstr_Append(cmdLine,locate((options_IsSet(OPT_BIGLC1) ? "lc1b" : "lc1"),binDirs));
X
X if(options_IsSet(OPT_DEBUG)){
X dstr_Addf(cmdLine," -d%d",debugLevel);
X if(options_IsSet(OPT_OPTIMIZE)){
X warning("-g incompatible with -O, -O turned off");
X options_Clear(OPT_OPTIMIZE);
X }
X }
X
X if(options_IsSet(OPT_FFP))
X dstr_Addf(cmdLine," -ff");
X else if(options_IsSet(OPT_881))
X dstr_Addf(cmdLine," -f8");
X else if(options_IsSet(OPT_IEEE))
X dstr_Addf(cmdLine," -fi");
X else
X dstr_Addf(cmdLine," -fl");
X
X if(options_IsSet(OPT_SHORTINTS))
X dstr_Addf(cmdLine," -w");
X if(options_IsSet(OPT_LONGALIGN))
X dstr_Addf(cmdLine," -l");
X
X if(options_IsSet(OPT_020))
X dstr_Addf(cmdLine," -m2");
X else if(options_IsSet(OPT_030))
X dstr_Addf(cmdLine," -m3");
X
X if(options_IsSet(OPT_CATCH) && !options_IsSet(OPT_ABSDATA)){
X warning("+catch implies +abs-data");
X options_Set(OPT_ABSDATA);
X }
X
X dstr_Addf(cmdLine," -b%d",options_IsSet(OPT_ABSDATA) ? 0 : 1);
X dstr_Addf(cmdLine," -r%d",options_IsSet(OPT_ABSCODE) ? 0 : 1);
X
X if(options_IsSet(OPT_REGARGS))
X dstr_Addf(cmdLine,"r"); /* part of -r switch */
X
X {
X char buf[15], *p=buf;
X
X if(options_IsSet(OPT_ANSI)) *p++='a';
X if(options_IsSet(OPT_CPP)) *p++='+';
X if(options_IsSet(OPT_TRAD)) *p++='l', *p++='o';
X if(options_IsSet(OPT_REGARGS)) *p++='r';
X if(options_IsSet(OPT_PURESTRINGS)) *p++='s';
X
X if(p>buf){
X *p='\0';
X dstr_Addf(cmdLine," -c%s",buf);
X }
X }
X
X if(options_IsSet(OPT_COMPILE)){
X strcpy(tmpFile,tempDir);
X strcat(tmpFile,op->basename);
X strcat(tmpFile,".q");
X dstr_Addf(cmdLine," -o%s",tmpFile);
X }else{
X strcpy(tmpFile,op->basename);
X strcat(tmpFile,".pp");
X
X dstr_Addf(cmdLine," -o%s -p",tmpFile);
X }
X
X for(n=list_GetLen(undefines),els=list_GetEls(undefines); n>0; n--,els++){
X /*************************
X dstr_Addf(cmdLine," -u%s",(char *)*els);
X **************************/
X warning("-U%s ignored! (unimplemented)",(char *)*els);
X }
X
X addfList(cmdLine," -d%s",defines);
X addfList(cmdLine," %s",pass1PassThrus);
X
X for(n=list_GetLen(incDirs),els=list_GetEls(incDirs); n>0; n--,els++){
X char *id=(*els);
X int len=strlen(id);
X
X dstr_Addf(cmdLine," -i%s",*els);
X
X if(len>0 && id[len-1]!=':' && id[len-1]!='/')
X dstr_Addf(cmdLine,"/");
X }
X
X dstr_Addf(cmdLine," %s",op->rootname);
X
X status=runCmd(cmdLine);
X if(status==0 && options_IsSet(OPT_EXEC) && !readable(tmpFile))
X status=1;
X
X DBUG_RETURN(int,status);
X}
X
X/* run the optimizer */
Xstatic int optimize(op)
Xstruct op *op;
X{
X DBUG_ENTER("optimize");
X
X dstr_Clear(cmdLine);
X dstr_Addf(cmdLine,"%s %s%s",locate("go",binDirs),tempDir,op->basename);
X
X addfList(cmdLine," %s",optPassThrus);
X
X DBUG_RETURN(int,runCmd(cmdLine));
X}
X
X/*
X * Run second pass of compiler on a single operand.
X */
Xstatic int pass2(op)
Xstruct op *op;
X{
X char objFile[MAXPATH];
X int status;
X
X#ifdef DBUG
X fprintf(stderr,"Entering pass2...\n");
X#endif
X
X DBUG_ENTER("pass2");
X
X dstr_Clear(cmdLine);
X
X dstr_Append(cmdLine,locate("lc2",binDirs));
X
X if(!options_IsSet(OPT_STACKCHECK))
X dstr_Addf(cmdLine," -v");
X
X strcpy(objFile,op->basename);
X strcat(objFile,".o");
X
X dstr_Addf(cmdLine," -o%s",objFile);
X
X dstr_Addf(cmdLine," %s%s",tempDir,op->basename);
X
X addfList(cmdLine," %s",pass2PassThrus);
X
X status=runCmd(cmdLine);
X if(status==0 && options_IsSet(OPT_EXEC) && !readable(objFile))
X status=1;
X
X DBUG_RETURN(int,status);
X}
X
X/*
X * I have not yet had occasion to use the macro assembler,so this
X * part is not yet implemented. If anyone wants to send me the
X * appropriate code, I will be glad to install it.
X */
Xstatic int assemble(op)
Xstruct op *op;
X{
X DBUG_ENTER("assemble");
X warning("assembly pass not yet implemented");
X DBUG_RETURN(int,1);
X}
X
Xstatic void filteredOutputFrom(source,filter)
XFILE *source;
Xchar **filter;
X{
X char buf[200];
X
X DBUG_ENTER("FilteredOutputFrom");
X
X while(!feof(source)){
X char **ignore;
X
X fgets(buf,sizeof(buf),source);
X
X for(ignore=filter; *ignore!=NULL; ignore++)
X if(strncmp(*ignore,buf,strlen(*ignore))==0)
X break;
X
X if(*ignore==NULL)
X fputs(buf,stdout);
X }
X
X DBUG_VOID_RETURN;
X}
X
X#ifdef AMIGA
X
Xstatic int execToFile(cmd,sink)
Xchar *cmd;
XFILE *sink;
X{
X /* this is a dopey version that uses Execute, since I can't get fork to work */
X long fh;
X
X DBUG_ENTER("execToFile");
X
X if(sink==NULL)
X fh=0;
X else
X fh=chkufb(fileno(sink))->ufbfh;
X
X DBUG_RETURN(int,Execute(cmd,0L,fh)!=(-1));
X
X#if 0
X char *argv[50],**argp=argv;
X struct ProcID child;
X static struct FORKENV env={0,0,0,0,0,NULL};
X int i;
X
X DBUG_ENTER("execToFile");
X
X if(cmd==NULL)
X DBUG_RETURN(int,1);
X
X /* this is sort of stupid, cause forkv will just put them back together,
X * but oh well...
X */
X *argp=strtok(cmd," \t");
X while(*argp!=NULL)
X *++argp=strtok(NULL," \t");
X
X if(sink==NULL)
X env.std_out=0;
X else{
X struct UFB *ufb=chkufb(fileno(sink));
X int i;
X
X printf("argv[%d]:",argp-argv);
X for(argp=argv;*argp!=NULL;argp++)
X printf(" %s",*argp);
X putchar('\n');
X
X printf("env: %d, %d, %d, %d, %d, %d\n",
X env.priority, env.stack, env.std_in, env.std_out,
X env.console, env.msgport);
X
X printf("ufb==0x%x, fh==0x%x, go? ",ufb,ufb->ufbfh);
X
X fflush(stdout);
X
X env.std_out=ufb->ufbfh; /* magic to get amigados handle from FILE */
X }
X
X if((i=forkv(argv[0],argv,&env,&child))==-1){
X poserr("forkv");
X DBUG_RETURN(int,1);
X }
X
X printf("Fork returns: %d\n",i);
X
X DBUG_RETURN(int,wait(&child));
X#endif
X}
X
X#endif
X
Xstatic int runCmd(cmd)
Xstruct dstr *cmd;
X{
X int status;
X char *buf=dstr_GetBuf(cmd);
X
X DBUG_ENTER("RunCommand");
X
X DBUG_3("cmd","execute '%s'",buf);
X if(options_IsSet(OPT_ECHO)){
X puts(buf);
X fflush(stdout);
X }
X
X CHECK_ABORT;
X
X if(options_IsSet(OPT_EXEC)){
X FILE *sink;
X
X if(sinkFile!=NULL && options_IsSet(OPT_FILTER)){
X sink=fopen(sinkFile,"w+");
X if(sink==NULL)
X perror(sinkFile);
X }else
X sink=NULL;
X
X status=execToFile(buf,sink);
X DBUG_3("sys","subcommand returns status %d",status);
X
X if(sink!=NULL){
X rewind(sink);
X filteredOutputFrom(sink,filteredPrefixes);
X fclose(sink);
X unlink(sinkFile);
X }
X
X DBUG_RETURN(int,status);
X }else
X DBUG_RETURN(int,0);
X}
X
X/*
X * Look through the list of paths pointed to by "vec" until we find
X * a file with name given pointed to by "namep". If none is found,
X * the name pointed to by namep is returned.
X */
Xstatic char *locate(name,paths)
Xchar *name;
Xstruct list *paths;
X{
X static char namebuf[MAXPATH];
X void **els;
X int n;
X
X DBUG_ENTER("locate");
X
X if(strchr(name,':')!=NULL || *name=='/')
X return name; /* absolute */
X
X for(n=list_GetLen(paths),els=list_GetEls(paths); n>0; n--,els++){
X int len=strlen((char *)*els);
X
X strcpy(namebuf,(char *)*els);
X if(len>0 && namebuf[len-1]!=':' && namebuf[len-1]!='/')
X strcat(namebuf,"/");
X strcat(namebuf,name);
X
X DBUG_3("try","look for '%s'",namebuf);
X if(readable(namebuf)){
X name=namebuf;
X break;
X }
X }
X
X DBUG_RETURN(char *,name);
X}
X
X/*
X * Check to see if the file exists and is readable.
X */
Xstatic int readable(name)
Xchar *name;
X{
X register int status=0;
X register long fildes;
X
X DBUG_ENTER("readable");
X
X#ifdef unix
X fildes=open(name,O_RDONLY);
X if(fildes >= 0){
X (void) close(fildes);
X status=1;
X }
X#else
X fildes=Lock(name,ACCESS_READ);
X if(fildes != 0){
X UnLock(fildes);
X status=1;
X }
X#endif
X
X DBUG_RETURN(int,status);
X}
X
X/*
X * If an executable is made from a single C file, the normal behavior
X * for the unix environment is to treat the .o file as an intermediate
X * file and remove it, so we follow suit.
X */
Xstatic void cleanObjects(mustExist)
Xint mustExist;
X{
X int n;
X void **els;
X
X DBUG_ENTER("cleanObjects");
X
X for(n=list_GetLen(ops),els=list_GetEls(ops); n>0; n--,els++){
X char buf[MAXPATH];
X struct op *op=(struct op *)*els;
X
X if(!op_IsO(op)){
X strcpy(buf,op->basename);
X strcat(buf,".o");
X if(unlink(buf)!=0 && mustExist)
X warning("can't delete '%s'",buf);
X }
X }
X
X DBUG_VOID_RETURN;
X}
SHAR_EOF
echo "extracting cc.doc"
sed 's/^X//' << \SHAR_EOF > cc.doc
X CC: a unix-like compiler driver for amiga lattice-c (that also
X filters out stupid messages!)
X
X USAGE:
X cc [args] file...
X
X Arguments are ([x] means x is optional):
X
X file A file to compile or link. Currently, only .c and .o
X are understood, although supporting .s files would
X probably be pretty simple.
X
X -o execfile Write the resulting executable to EXECFILE (only
X meaningful when linking).
X
X -c Don't link the object file, just leave it there.
X
X -g[num] Compile in debugging info, using debug-level NUM.
X -O Use the global optimizer (incompatible with -g).
X -P Just pre-process the file, creating a .pp file.
X
X -l libname Add LIBNAME.lib to the list of libraries.
X
X -I dir Add the directory DIR to the path searched for include
X files.
X -D define Add DEFINE a pre-processor define; it can be just a name
X or name=value.
X -U undefin Undefine the symbol UNDEFINE (this really doesn't work).
X -L libdir Add the directory LIBDIR to the path searched for
X libraries.
X -B bindir Add the directory BINDIR to the path searched for
X binaries.
X
X -px string Put STRING on the command line of compiler pass X, where
X X is one of: 1-- pass1; 2-- pass2; o-- optimizer;
X and l-- linker. This switch can be used to get at
X compiler features that cc doesn't directly support,
X although it'd be better to just add the feature to cc
X (it shouldn't be too hard)-- and send the change
X back to me (bader+@andrew.cmu.edu)!
X
X -t tempdir Use TEMPDIR as the place to put temporary files.
X
X +ansi Enforce ansi fascism.
X +cpp Compat with c++.
X +trad Use traditional style cpp.
X
X +[no-]abs-code Use long (absolute) addressing for function
X calls.
X +[no-]abs-data Use long (absolute) addressing for data.
X
X +[no-]reload-a4 Reload reg a4 in each function.
X +[no-]short-ints Use short integers.
X +[no-]reg-args Use register argument passing.
X +[no-]long-align Align everything to long boundaries.
X +[no-]stack-check Put stack-checking into the func prolog.
X +[no-]pure-strings Put strings in the text segment.
X
X +ffp Use motorola fast floating point.
X +881 Compile for a 68881.
X +ieee Ieee floating point.
X
X +68k Compile for a 68000 and up.
X +020 Compile for a 68020 and up.
X +030 Compile for a 68030.
X
X +[no-]detach Make a program that runs in the background.
X +[no-]tiny-main Use tinymain (this doesn't work).
X +[no-]resident Try and make resident-able.
X +[no-]catch Compile in code to try and catch exceptions.
X
X +[no-]optimize Optimize the obj module.
X +[no-]link Link the object modules.
X +[no-]compile (Otherwise, just pre-process).
X +[no-]assemble Emit object-modules (else assembly).
X +[no-]debug Produce debugging info.
X
X +[no-]echo Echo what we execute.
X +[no-]filter Filter out yucky message from passes.
X +[no-]exec Actually run each pass.
X
X +[no-]big-lc1 Run lc1b instead of lc1.
X
X DEFAULTS:
X The default options are: +compile +link +stack-check +exec +filter
X
X The default output file is "a.out".
X
X The default temp directory is "t:".
X
X The default debug level when just -g (or +debug) is specified is 3.
X
X The default libraries are: "-lc", "-lamiga".
X
X NOTES:
X The library -lm is replaced by whichever math library is appropiate
X given other switches (like +ieee or +ffp), and -lc is replaced by
X the appropiate c library-- so be and sure to pass the same set of
X switches to cc when linking as you do when compiling (with -c) the
X object files!
X
X This version of cc is intended for use with lattice c version 5.
X
X BUGS:
X I haven't nearly tested all the possible combinations of options.
X
X The libraries supplied by lattice aren't complete, so some combos
X of switches may not be possible (e.g., +reg-args and +ieee-- lattice
X doesn't supply a libieeer.lib, and so linking fails in this case).
X
X -U doesn't work.
X
X -S doesn't work (and isn't ever likely too unless lattice makes
X omd a much better program).
X
X Compiling .s (assembly) files isn't implemented, even though it's
X probably pretty simple, using asm. I just never needed it...
X
X AUTHOR:
X Miles Bader (bader+@andrew.cmu.edu)
X from an earlier program by Fred Fish.
SHAR_EOF
echo "extracting config.h"
sed 's/^X//' << \SHAR_EOF > config.h
X/*
X * configuration file for cc; easily re-configurable stuff goes here.
X * March 1989, Miles Bader
X */
X
X/*
X * this file contains declarations, so it can only be included in one source file
X */
X
X#define MAXPATH 200 /* max length of a path */
X
X/* What to call executable if not specified. If NULL, named after 1st source file */
X#define DEFAULT_EXEC "a.out"
X
X/* must be a prefix; i.e., needs a slash or a colon on the end */
X#define TEMPDIR "T:" /* Keep intermediate files in temp directory */
X/* #define TEMPDIR "" */ /* Keep intermediate files in current dir */
X
X/* The file for filtering compiler pass output. If NULL, no filtering is done */
X#define SINKFILE "T:__cc_sink"
X
X#define DEFAULT_DEBUGLEVEL 3 /* default debug level if just -g is given */
X
X/* Listf of default options. Note that not having _EXEC, _COMPILE, _ASSEMBLE,
X * and _LINK set by default would be very wierd
X */
Xint defaultOptions[]={
X OPT_COMPILE, /* compile things! */
X OPT_ASSEMBLE, /* make object files! */
X OPT_EXEC, /* execute passes! */
X OPT_LINK, /* link into executable! */
X OPT_FILTER, /* filter out obnoxious messages */
X OPT_STACKCHECK, /* enable stack checking */
X 0
X};
X
X/* initial contents of some lists; &insertMark is where additional elements go */
Xchar *libDirsInit[]={"",&insertMark,"lib:",NULL};
Xchar *incDirsInit[]={&insertMark,"include:",NULL};
Xchar **binDirsInit=NULL;
Xchar **definesInit=NULL;
Xchar **undefinesInit=NULL;
Xchar *libsInit[]={&insertMark,"lc","amiga",NULL};
X
X/* prefixes that are filtered out of the compiler output stream */
Xchar *filteredPrefixes[]={
X "\n", /* blank lines */
X "Copyright", /* copyright noticed */
X "Lattice", /* lattice advertisements */
X
X /* lc2 */
X "Module size",
X
X /* blink */
X "Blink - Version",
X "Enter a DEFINE value", /* input is impossible anyway... */
X "BLINK Complete",
X "Final output file size",
X NULL
X};
SHAR_EOF
echo "extracting dstr.c"
sed 's/^X//' << \SHAR_EOF > dstr.c
X/*
X * dynamic strings
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "dstr.h"
X
Xstruct dstr *dstr_Create(initsize)
Xint initsize;
X{
X struct dstr *n=NEW(struct dstr);
X
X DBUG_ENTER("dstr_Create");
X
X if(n==NULL)
X fatal("couldn't allocate a dstr");
X
X n->buf=malloc(initsize+1);
X
X if(n->buf==NULL)
X fatal("couldn't allocate dstr of size %d",initsize);
X
X n->max=initsize;
X n->len=0;
X *n->buf='\0';
X
X DBUG_RETURN(struct dstr *,n);
X}
X
Xvoid dstr_Free(ds)
Xstruct dstr *ds;
X{
X DBUG_ENTER("dstr_Free");
X
X if(ds->buf!=NULL)
X FREE(ds->buf);
X FREE(ds);
X
X DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Clear(ds)
Xstruct dstr *ds;
X{
X ds->len=0;
X *ds->buf='\0';
X}
X
Xvoid dstr_Append(ds,str)
Xstruct dstr *ds;
Xchar *str;
X{
X int len=strlen(str);
X
X DBUG_ENTER("dstr_Append");
X
X if(len+ds->len>ds->max){
X ds->max+=len+len;
X ds->buf=(char *)realloc((void *)ds->buf,ds->max);
X
X if(ds->buf==NULL)
X fatal("couldn't extend a dstr to %d chars",ds->max);
X }
X
X strcpy(ds->buf+ds->len,str);
X ds->len+=len;
X
X DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Set(ds,str)
Xstruct dstr *ds;
Xchar *str;
X{
X DBUG_ENTER("dstr_Set");
X
X ds->len=0;
X dstr_Append(ds,str);
X
X DBUG_VOID_RETURN;
X}
X
Xvoid dstr_Addf(ds,fmt,a1,a2,a3,a4,a5,a6,a7)
Xstruct dstr *ds;
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X char buf[500];
X
X DBUG_ENTER("dstr_Addf");
X
X sprintf(buf,fmt,a1,a2,a3,a4,a5,a6,a7);
X
X DBUG_2("buf",buf);
X
X dstr_Append(ds,buf);
X
X DBUG_VOID_RETURN;
X}
SHAR_EOF
echo "extracting dstr.h"
sed 's/^X//' << \SHAR_EOF > dstr.h
X/*
X * dynamic strings
X * March 1989, Miles Bader
X */
X
Xstruct dstr {
X int max,len;
X char *buf;
X};
X
Xstruct dstr *dstr_Create();
Xvoid dstr_Free();
Xvoid dstr_Clear();
Xvoid dstr_Set();
Xvoid dstr_Append();
Xvoid dstr_Addf();
X
X#define dstr_GetBuf(d) ((d)->buf)
X#define dstr_GetLen(d) ((d)->len)
SHAR_EOF
echo "extracting err.c"
sed 's/^X//' << \SHAR_EOF > err.c
X/*
X * these are in a separate file so the compiler doesn't bitch about mismatched
X * arguments
X */
X
X#include <stdio.h>
X
X#include "common.h"
X
X/*VARARGS1*/
Xvoid warning(fmt,a1,a2,a3,a4,a5,a6,a7)
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X fputs("cc: warning: ",stderr);
X fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
X putc('\n',stderr);
X (void) fflush(stderr);
X}
X
X/*VARAS1*/
Xvoid fatal(fmt,a1,a2,a3,a4,a5,a6,a7)
Xchar *fmt;
Xchar *a1,*a2,*a3,*a4,*a5,*a6,*a7;
X{
X fputs("cc: error: ",stderr);
X fprintf(stderr,fmt,a1,a2,a3,a4,a5,a6,a7);
X putc('\n',stderr);
X (void) fflush(stderr);
X exit(1);
X}
SHAR_EOF
echo "extracting list.c"
sed 's/^X//' << \SHAR_EOF > list.c
X/*
X * expandable lists
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "list.h"
X
X#define BUMPSIZE 5 /* grow list this much at a time */
X
Xchar insertMark; /* dummy used for its address */
X
Xstruct list *list_Create(init)
Xvoid **init;
X{
X void **p,**q;
X struct list *l=NEW(struct list);
X
X DBUG_ENTER("list_Create");
X
X if(l==NULL)
X fatal("couldn't allocate a list");
X
X l->num=0;
X
X l->insertionPoint=(-1);
X
X for(p=init; p!=NULL && *p!=NULL; p++)
X if(*p==&insertMark)
X l->insertionPoint=l->num;
X else
X l->num++;
X
X l->els=(void **)malloc(l->num*sizeof(void *));
X
X if(l->els==NULL && l->num>0 /* ANSI compat */)
X fatal("couldn't allocate initial list elements");
X
X for(p=init,q=l->els; p!=NULL && *p!=NULL; p++)
X if(*p!=&insertMark)
X *q++=(*p);
X
X l->max=l->num;
X if(l->insertionPoint<0)
X l->insertionPoint=l->num; /* default is at end */
X
X l->freeProc=NULL;
X
X DBUG_RETURN(struct list *,l);
X}
X
Xvoid list_Free(l)
Xstruct list *l;
X{
X DBUG_ENTER("list_Free");
X
X if(l->freeProc!=NULL){
X void **els;
X int n;
X
X DBUG_4("free","using freeProc on %d els: 0x%x",l->num,l->freeProc);
X
X for(n=l->num,els=l->els; n>0; n--,els++){
X DBUG_3("free","freeProc(0x%x)",*els);
X (*l->freeProc)(*els);
X }
X }
X
X if(l->els!=NULL){
X DBUG_3("free","freeing els: 0x%x",l->els);
X FREE(l->els);
X }
X
X DBUG_3("free","freeing list: 0x%x",l);
X
X FREE(l);
X
X DBUG_VOID_RETURN;
X}
X
Xvoid list_Add(l,e)
Xstruct list *l;
Xvoid *e;
X{
X int i;
X
X DBUG_ENTER("list_Add");
X
X if(l->num>=l->max){
X l->max+=BUMPSIZE;
X l->els=(void **)realloc((void *)l->els,l->max*sizeof(void *));
X
X if(l->els==NULL)
X fatal("couldn't extend a list to %d elements",l->max);
X }
X
X for(i=l->num; i>l->insertionPoint; i--)
X l->els[i]=l->els[i-1];
X
X l->els[l->insertionPoint++]=e;
X
X l->num++;
X
X DBUG_VOID_RETURN;
X}
SHAR_EOF
echo "extracting list.h"
sed 's/^X//' << \SHAR_EOF > list.h
X/*
X * expandable lists
X * March 1989, Miles Bader
X */
X
Xextern char insertMark;
X
Xstruct list {
X int num,max;
X int insertionPoint; /* where a new element gets added */
X void **els;
X void (*freeProc)(); /* if non-NULL, used to free elements */
X};
X
Xstruct list *list_Create(void **initEls);
Xvoid list_Free(struct list *l);
Xvoid list_Add(struct list *l,void *el);
X
X#define list_GetEls(l) ((l)->els)
X#define list_GetLen(l) ((l)->num)
X
X#define list_SetFree(l,fp) ((l)->freeProc=fp)
SHAR_EOF
echo "extracting op.c"
sed 's/^X//' << \SHAR_EOF > op.c
X/*
X * file operands
X * March 1989, Miles Bader (orig from cc.c by fred fish)
X */
X
X#include "common.h"
X#include "op.h"
X
X/*
X * Split an operand name into rootname, basename, and suffix
X * components. The rootname is the full name, minus any suffix,
X * but including any prefix. The basename is the rootname minus
X * any prefix. The suffix is anything after the last '.' character.
X * Only the suffix is allowed to be the null string.
X */
Xstruct op *op_Create(filename)
Xchar *filename;
X{
X char *split;
X extern char *strrchr();
X struct op *op=NEW(struct op);
X
X DBUG_ENTER("op_Create");
X
X DBUG_3("ops", "create op '%s'",filename);
X
X if(op==NULL)
X fatal("couldn't allocate an op");
X
X op->rootname=filename;
X
X split=strrchr(filename,'/');
X if(split==NULL)
X split=strrchr(filename,':');
X
X if(split==NULL)
X op->basename=filename;
X else
X op->basename=++split;
X
X split=strrchr(filename,'.');
X if(split==NULL)
X op->suffix="";
X else{
X *split++='\0';
X op->suffix=split;
X }
X
X DBUG_3("ops","rootname '%s'",op->rootname);
X DBUG_3("ops","basename '%s'",op->basename);
X DBUG_3("ops","suffix '%s'",op->suffix);
X
X DBUG_RETURN(struct op *,op);
X}
X
Xvoid op_Free(op)
Xstruct op *op;
X{
X FREE(op);
X}
SHAR_EOF
echo "extracting op.h"
sed 's/^X//' << \SHAR_EOF > op.h
X/*
X * file operands
X * March 1989, Miles Bader (orig from cc.c by fred fish)
X */
X
X/*
X * Command line arguments that represent files to be compiled, assembled,
X * or linked, are kept track of as "ops". If, for example,
X * the file name is "df0:mydir/junk.c", then the rootname is
X * "df0:mydir/junk", the basename is "junk", and the suffix is "c".
X * String suffixes are used, rather than single character suffixes, to
X * allow use of names with multicharacter suffixes.
X */
X
Xstruct op{ /* Info about each operand (non option) */
X char *rootname; /* Name minus any suffix */
X char *basename; /* Name minus any prefix or suffix */
X char *suffix; /* suffix of operand */
X};
X
X/*
X * macros to determine the suffix type of a file given a pointer to
X * its operand structure.
X */
X#define op_IsC(op) (strcmp(op->suffix,"c")==0)
X#define op_IsS(op) (strcmp(op->suffix,"s")==0)
X#define op_IsO(op) (strcmp(op->suffix,"o")==0)
X
Xstruct op *op_Create(char *name);
Xvoid op_Free(struct op *op);
SHAR_EOF
echo "extracting options.c"
sed 's/^X//' << \SHAR_EOF > options.c
X/*
X * compiler options processing
X * March 1989, Miles Bader
X */
X
X#include "common.h"
X#include "options.h"
X
Xlong globalOpts[MAXOPTS/BITSPERLONG];
X
Xstruct option {
X char *name;
X int opt;
X int *set;
X};
X
X/* pre-processor compatibility modes */
Xint ppOptSet[]={OPT_TRAD, OPT_ANSI, OPT_CPP, 0};
X
X/* cpu-types */
Xint cpuOptSet[]={OPT_68K, OPT_020, OPT_030, 0};
X
X/* types of floating point support */
Xint floatOptSet[]={OPT_FFP, OPT_IEEE, OPT_881, 0};
X
Xstruct option optionlist[]={
X/* name mask excludes */
X
X /* parsing */
X {"ansi", OPT_ANSI, ppOptSet},
X {"c++", OPT_CPP, ppOptSet},
X {"traditional", OPT_TRAD, ppOptSet},
X
X /* code gen */
X {"abs-code", OPT_ABSCODE},
X {"abs-data", OPT_ABSDATA},
X
X {"reg-args", OPT_REGARGS},
X {"reload-a4", OPT_RELOADA4},
X {"short-ints", OPT_SHORTINTS},
X {"long-align", OPT_LONGALIGN},
X {"stack-check", OPT_STACKCHECK},
X
X {"pure-strings", OPT_PURESTRINGS},
X
X {"68k", OPT_68K, cpuOptSet},
X {"020", OPT_020, cpuOptSet},
X {"030", OPT_030, cpuOptSet},
X
X {"881", OPT_881, floatOptSet},
X {"ffp", OPT_FFP, floatOptSet},
X {"ieee", OPT_IEEE, floatOptSet},
X
X /* linking */
X {"detach", OPT_DETACH},
X {"resident", OPT_RESIDENT},
X {"tiny-main", OPT_TINYMAIN},
X {"catch", OPT_CATCH},
X
X {"optimize", OPT_OPTIMIZE},
X {"link", OPT_LINK},
X {"compile", OPT_COMPILE},
X {"assemble", OPT_ASSEMBLE},
X {"debug", OPT_DEBUG},
X
X {"echo", OPT_ECHO},
X {"filter", OPT_FILTER},
X {"exec", OPT_EXEC},
X
X {"big-lc1", OPT_BIGLC1},
X
X NULL
X};
X
Xvoid options_SetByName(optname)
Xchar *optname;
X{
X struct option *opt;
X int not=FALSE;
X
X if(strncmp(optname,"no-",3)==0){
X optname+=3;
X not=TRUE;
X }
X
X for(opt=optionlist; opt->name!=NULL; opt++)
X if(strcmp(optname,opt->name)==0){
X if(not){
X if(opt->set!=NULL)
X fatal("%s is not a boolean option",opt);
X else
X options_Clear(opt->opt);
X }else{
X if(opt->set!=NULL){
X int *clear;
X for(clear=opt->set; *clear!=0; clear++)
X options_Clear(*clear);
X }
X
X options_Set(opt->opt);
X }
X
X break;
X }
X
X if(opt->name==NULL)
X fatal("unknown option: %s",optname);
X}
X
Xvoid options_Init()
X{
X int i;
X for(i=0; i<(MAXOPTS/BITSPERLONG); i++)
X globalOpts[i]=0;
X}
SHAR_EOF
echo "extracting options.h"
sed 's/^X//' << \SHAR_EOF > options.h
X/*
X * compiler options
X * March 1989, Miles Bader
X */
X
X/* increase this for more options */
X#define MAXOPTS 64
X
X#ifndef BITSPERLONG
X#define BITSPERLONG 32
X#endif
X
Xextern long globalOpts[MAXOPTS/BITSPERLONG];
X
X#define options_IsSet(opt) \
X (globalOpts[(opt)/BITSPERLONG]&(1L<<((opt)%BITSPERLONG)))
X#define options_Set(opt) \
X (globalOpts[(opt)/BITSPERLONG]|=(1L<<((opt)%BITSPERLONG)))
X#define options_Clear(opt) \
X (globalOpts[(opt)/BITSPERLONG]&=~(1L<<(long)((opt)%BITSPERLONG)))
X
Xvoid options_SetByName(char *optname);
Xvoid options_Init();
X
X
X#define OPT_NONE 0
X
X#define OPT_ANSI 1 /* enforce ansi fascism */
X#define OPT_CPP 2 /* compat with c++ */
X#define OPT_TRAD 3 /* use traditional style cpp */
X
X#define OPT_ABSCODE 4 /* use long (absolute) addressing for function calls */
X#define OPT_ABSDATA 5 /* use long (absolute) addressing for data */
X
X#define OPT_RELOADA4 6 /* reload reg a4 in each function */
X#define OPT_SHORTINTS 7 /* use short integers */
X#define OPT_REGARGS 8 /* use register argument passing */
X#define OPT_LONGALIGN 9 /* align everything to long boundaries */
X#define OPT_STACKCHECK 10 /* put stack-checking into the func prolog */
X#define OPT_PURESTRINGS 11 /* put strings in the text segment */
X
X#define OPT_FFP 12 /* use mot fast floating point */
X#define OPT_881 13 /* compile for a 68881 */
X#define OPT_IEEE 14 /* ieee floating point */
X
X#define OPT_68K 15 /* compile for a 68000 and up */
X#define OPT_020 16 /* compile for a 68020 and up */
X#define OPT_030 17 /* compile for a 68030 */
X
X#define OPT_DETACH 18 /* make a program that runs in the background */
X#define OPT_TINYMAIN 19 /* use tinymain (this doesn't work) */
X#define OPT_RESIDENT 20 /* try and make resident-able */
X#define OPT_CATCH 21 /* compile in code to try and catch exceptions */
X
X#define OPT_OPTIMIZE 22 /* optimize the obj module */
X#define OPT_LINK 23 /* link the object modules */
X#define OPT_COMPILE 24 /* (otherwise, just pre-process) */
X#define OPT_ASSEMBLE 25 /* emit object-modules (else assembly) */
X#define OPT_DEBUG 26 /* produce debugging info */
X
X#define OPT_ECHO 27 /* echo what we execute */
X#define OPT_FILTER 28 /* filter out yucky message from passes */
X#define OPT_EXEC 29 /* actually run each pass */
X
X#define OPT_BIGLC1 30 /* run lc1b instead of lc1 */
SHAR_EOF
echo "End of archive 1 (of 1)"
# if you want to concatenate archives, remove anything after this line
exit